using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using System.IO;
using System.Reflection;
using RevitCopilot.Config.Options;
using RevitCopilot.Services;

namespace RevitCopilot;
public static class Host
{
    private static IHost? host;
    public static void Start()
    {   
        // 默认情况下CreateApplicationBuilder()会自动:将ContentRootPath设置为程序集目录
        // 自动加载程序集目录下的appsettings.json，根据环境加载appsettings.{Environment}.json
        // 只需确保你的appsettings.json文件在输出目录中
        //【1】使用默认配置创建主机
        var builder = Microsoft.Extensions.Hosting.Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
        {
            // 自动设置ContentRootPath和配置文件基路径SetBasePath为Revit插件目录
            ContentRootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
        });
        // 启用选项模式，注册并验证配置，使用数据注解验证，应用启动时验证
        builder.Services.AddOptions<SocketSettings>()
            .Bind(builder.Configuration.GetSection(SocketSettings.SectionName))
            .ValidateDataAnnotations()  
            .ValidateOnStart();        
        //【2】配置日志为Serilog（写入文件和控制台）
        //默认的Logg无法写入文件，清除自带logg配置，添加serilog
        //Serilog.Extensions.Hosting;Serilog.Sinks.File;Serilog.Sinks.Console
        builder.Logging.ClearProviders();
        // 构建完整日志目录路径并确保目录存在
        var logDirectory = Path.Combine(builder.Environment.ContentRootPath, "Logs");
        Directory.CreateDirectory(logDirectory); 
        var logPath = Path.Combine(logDirectory, "RevitCopilot.log");
        builder.Logging.AddSerilog(new LoggerConfiguration()
            .WriteTo.File(logPath , rollingInterval: RollingInterval.Day)
            .WriteTo.Console()
            .CreateLogger());
        //【3】添加服务如View,ViewModel,Service
        builder.Services.AddSingleton<SocketService>();
        builder.Services.AddTransient<ExecCommandService>();
        host = builder.Build();
        host.Start();
    }
    public static void Stop()
    {
        host!.StopAsync().GetAwaiter().GetResult();
    }
    public static T GetService<T>() where T : class
    {
        return host!.Services.GetRequiredService<T>();
    }
}